function Shader() {
    this._vs = null;
    this._fs = null;
    this._program = null;
}

Shader.prototype = {
compile : function( gl, src, isFragmentShader) {
    var shader;
    if ( isFragmentShader)
        this._fs = shader = gl.createShader( gl.FRAGMENT_SHADER);
    else
        this._vs = shader = gl.createShader( gl.VERTEX_SHADER);
    if ( !shader)
        return -1;
    
    gl.shaderSource( shader, src);
    gl.compileShader( shader);
    if ( !gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.log( gl.getShaderInfoLog(shader));
        return -1;
    }
    return 0;
},

link : function( gl) {
    this._program = gl.createProgram();
    gl.attachShader( this._program, this._vs);
    gl.attachShader( this._program, this._fs);
    gl.linkProgram( this._program);
    if ( !gl.getProgramParameter(this._program, gl.LINK_STATUS)) {
        return -1;
    }
    return 0;
},

attrib : function( gl, name, notArray) {
    var index = gl.getAttribLocation( this._program, name);
    if ( index < 0)
        return -1;
    var atObj = new Object();
    atObj.index = index;
    if ( !notArray){
        gl.enableVertexAttribArray( index);
        atObj.isArray = 1;
    }
    this[name] = atObj;
    return 0;
},

_setUniformObj : function( gl, obj) {
    var r = gl.getUniform( this._program, obj.index);
    var c = r.__proto__.constructor;
    if ( c == Float32Array) {
       switch( t.length) {
       case 2:
       case 3:
       case 4:
       	break;
       case 9:
       	break;
       default:
       }
    }
},

uniform : function( gl, name) {
    var index = gl.getUniformLocation( this._program, name);
    if ( index == null || index < 0)
        return -1;
    var obj = {};
    obj.index = index;
    this._setUniformObj( gl, obj);
    obj.setMatrix = function( mat) {
        gl.uniformMatrix4fv( this.index, false, mat);
    };
    obj.setSampler = function( s) {
        gl.uniform1i( s, 0);
    };
    this[name] = obj;
    return 0;
},

}

function ShaderMgr(){
    this._shaders = new Map();
}

ShaderMgr.prototype = {
set : function( gl, key, vsSrc, fsSrc) {
    var shader = new Shader();
    if ( shader.compile( gl, vsSrc))
        return null;
    if ( shader.compile( gl, fsSrc, true))
        return null;
    if ( shader.link(gl))
        return null;
    this._shaders.put( key, shader);
    return shader;
},

get : function( key) {
    return this._shaders.get( key);
},
}

mix.shaderMgr = new ShaderMgr();